{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Part 12: এনক্রিপ্ট করা ডেটাতে একটি এনক্রিপ্ট করা এনএনকে প্রশিক্ষণ দিন (Train an Encrypted NN on Encrypted Data)\n",
    "এই নোটবুকটিতে, আমরা মডেল এবং ডেটা উভয়ই এনক্রিপ্ট করা অবস্থায় নিউরাল নেটওয়ার্ক (neural network) প্রশিক্ষণ (এবং পূর্বাভাস) সম্পাদনের জন্য আমরা এতদূর শিখেছি এমন সমস্ত কৌশল ব্যবহার করব।\n",
    "\n",
    "বিশেষত, আমরা আমাদের কাস্টম অটোগ্রাড ইঞ্জিন উপস্থাপন করি যা এনক্রিপ্ট করা গণনাগুলিতে কাজ করে।\n",
    "\n",
    "Authors:\n",
    "- Andrew Trask - Twitter: [@iamtrask](https://twitter.com/iamtrask)\n",
    "- Jason Paumier - Github: [@Jasopaum](https://github.com/Jasopaum)\n",
    "- Théo Ryffel - Twitter: [@theoryffel](https://twitter.com/theoryffel)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "অনুবাদক:\n",
    "\n",
    "- Sourav Das - Twitter: [@adventuroussrv](https://twitter.com/adventuroussrv)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Step 1: শ্রমিক এবং খেলনা ডেটা তৈরি করুন (Create Workers and Toy Data)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import torch\n",
    "import torch.nn as nn\n",
    "import torch.nn.functional as F\n",
    "import torch.optim as optim\n",
    "import syft as sy"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Set everything up\n",
    "hook = sy.TorchHook(torch) \n",
    "\n",
    "alice = sy.VirtualWorker(id=\"alice\", hook=hook)\n",
    "bob = sy.VirtualWorker(id=\"bob\", hook=hook)\n",
    "james = sy.VirtualWorker(id=\"james\", hook=hook)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# A Toy Dataset\n",
    "data = torch.tensor([[0,0],[0,1],[1,0],[1,1.]])\n",
    "target = torch.tensor([[0],[0],[1],[1.]])\n",
    "\n",
    "# A Toy Model\n",
    "class Net(nn.Module):\n",
    "    def __init__(self):\n",
    "        super(Net, self).__init__()\n",
    "        self.fc1 = nn.Linear(2, 2)\n",
    "        self.fc2 = nn.Linear(2, 1)\n",
    "\n",
    "    def forward(self, x):\n",
    "        x = self.fc1(x)\n",
    "        x = F.relu(x)\n",
    "        x = self.fc2(x)\n",
    "        return x\n",
    "model = Net()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Step 2: মডেল এবং ডেটা এনক্রিপ্ট করুন (Encrypt the Model and Data)\n",
    "Multi-Party Computation\n",
    "এখানে এনক্রিপশন দুটি ধাপে আসে। যেহেতু সিকিউর মাল্টি-পার্টির গণনা (Multi-Party Computation) কেবলমাত্র পূর্ণসংখ্যার (integers) উপর কাজ করে, দশমিক (decimal) পয়েন্ট (যেমন ওজন এবং ক্রিয়াকলাপ/such as weights and activations) সহ সংখ্যার বেশি পরিচালনা করার জন্য, আমাদের সুনির্দিষ্ট (Fixed) যথার্থতা ব্যবহার করে আমাদের সমস্ত সংখ্যা এনকোড করা দরকার যা দশমিক সুস্পষ্টতার কয়েকটি বিটস (bits) দেয়। আমরা .fix_precision () কল করে এটি করি।\n",
    "\n",
    "তারপরে আমরা অন্য ডেমোগুলির জন্য যেমনটি .share() কল করতে পারি, যা অ্যালিস এবং ববের ( Alice and Bob) মধ্যে ভাগ করে সমস্ত মানকে এনক্রিপ্ট করে। নোট করুন যে আমরা requires_grad ট্রুতে (True) ও সেট করেছিলাম যা এনক্রিপ্ট করা ডেটার জন্য একটি বিশেষ অটোগ্রাড (autograd) পদ্ধতি যুক্ত করে। প্রকৃতপক্ষে, যেহেতু সিকিউর মাল্টি-পার্টির (Secure Multi-Party) গণনা ফ্লোট (float) মানগুলিতে কাজ করে না, তাই আমরা সাধারণ পাইটর্চ অটোগ্র্যাড ব্যবহার করতে পারি না। অতএব, আমাদের একটি বিশেষ অটোগ্রাডটেনসর নোড যুক্ত করা দরকার যা ব্যাকপ্রসারণের জন্য গ্রেডিয়েন্ট গ্রাফটি গণনা করে। এটিতে একটি অটোগ্রাডটেন্সার অন্তর্ভুক্ত রয়েছে তা দেখতে আপনি এই উপাদানটির যে কোনওটি মুদ্রণ করতে পারেন।"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# We encode everything\n",
    "data = data.fix_precision().share(bob, alice, crypto_provider=james, requires_grad=True)\n",
    "target = target.fix_precision().share(bob, alice, crypto_provider=james, requires_grad=True)\n",
    "model = model.fix_precision().share(bob, alice, crypto_provider=james, requires_grad=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print(data)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Step 3: প্রশিক্ষণ (Train)\n",
    "\n",
    "এবং এখন আমরা সাধারণ টেনসর যুক্তি ব্যবহার করে প্রশিক্ষণ দিতে পারি।"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "opt = optim.SGD(params=model.parameters(),lr=0.1).fix_precision()\n",
    "\n",
    "for iter in range(20):\n",
    "    # 1) erase previous gradients (if they exist)\n",
    "    opt.zero_grad()\n",
    "\n",
    "    # 2) make a prediction\n",
    "    pred = model(data)\n",
    "\n",
    "    # 3) calculate how much we missed\n",
    "    loss = ((pred - target)**2).sum()\n",
    "\n",
    "    # 4) figure out which weights caused us to miss\n",
    "    loss.backward()\n",
    "\n",
    "    # 5) change those weights\n",
    "    opt.step()\n",
    "\n",
    "    # 6) print our progress\n",
    "    print(loss.get().float_precision())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "ক্ষতি আসলেই কমেছে!"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## নির্দিষ্ট নির্ভুলতার প্রভাব (Impact of fixed precision)\n",
    "আপনি ভাবতে পারেন যে কীভাবে সমস্ত এনক্রিপ্ট করা হ্রাস হ্রাসকে প্রভাবিত করে। প্রকৃতপক্ষে, তাত্ত্বিক গণনা সমান হওয়ায় সংখ্যাগুলি এনক্রিপ্ট করা প্রশিক্ষণের খুব কাছাকাছি। আপনি এনক্রিপশন ছাড়াই একই মডেল চালিয়ে এবং মডেলটির মতো মডেলটির একটি নির্ধারিত সূচনা দিয়ে এটি যাচাই করতে পারেন `__init__`:\n",
    "```\n",
    "with torch.no_grad():\n",
    "    self.fc1.weight.set_(torch.tensor([[ 0.0738, -0.2109],[-0.1579,  0.3174]], requires_grad=True))\n",
    "    self.fc1.bias.set_(torch.tensor([0.,0.1], requires_grad=True))\n",
    "    self.fc2.weight.set_(torch.tensor([[-0.5368,  0.7050]], requires_grad=True))\n",
    "    self.fc2.bias.set_(torch.tensor([-0.0343], requires_grad=True))\n",
    "```\n",
    "\n",
    "আপনি যে সামান্য পার্থক্যটি লক্ষ্য করতে পারেন তা স্থির নির্ভুলতায় রূপান্তর করার সময় সম্পাদিত মানগুলির বৃত্তাকার কারণে হয়। ডিফল্ট  `precision_fractional` 3 হয় এবং যদি আপনি এটি 2 এ নামেন তবে স্পষ্ট পাঠ্যের প্রশিক্ষণের সাথে বিভাজন বৃদ্ধি পায়, যখন আপনি চয়ন করেন এটি হ্রাস করে `precision_fractional = 4`."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# অভিনন্দন - সম্প্রদায় যোগদানের সময়! (Congratulations!!! - Time to Join the Community!_\n",
    "\n",
    "এই নোটবুক টিউটোরিয়ালটি সম্পন্ন করার জন্য অভিনন্দন! আপনি যদি এটি উপভোগ করেন এবং গোপনীয়তা সংরক্ষণ, AI এবং AI সরবরাহ চেইনের (ডেটা) বিকেন্দ্রীভূত মালিকানার দিকে আন্দোলনে যোগ দিতে চান, আপনি নিম্নলিখিত উপায়ে এটি করতে পারেন!\n",
    "\n",
    "### গিটহাবে পাইসিফ্ট কে স্টার দিন (Star PySyft on GitHub)\n",
    "\n",
    "আমাদের সম্প্রদায়কে সাহায্য করার সবচেয়ে সহজ উপায় হ'ল রিপোসিটোরি গুলোতে ষ্টার করা\n",
    " এটি আমরা যে অসাধারণ সরঞ্জামগুলি তৈরি করছি তার সচেতনতা বাড়াতে সহায়তা করে।\n",
    "\n",
    "- [Star PySyft](https://github.com/OpenMined/PySyft)\n",
    "\n",
    "### আমাদের স্ল্যাক যোগ দিন (Join our Slack!)\n",
    "\n",
    "সর্বশেষতম অগ্রগতিতে আপ টু ডেট রাখার সর্বোত্তম উপায় হ'ল আমাদের সম্প্রদায়ে যোগদান করা! আপনি ফর্মটি পূরণ করে এটি করতে পারেন [http://slack.openmined.org](http://slack.openmined.org)\n",
    "\n",
    "### একটি কোড প্রকল্পে যোগদান করুন! (Join a Code Project!)\n",
    "\n",
    "আমাদের সম্প্রদায়ে অবদান রাখার সর্বোত্তম উপায় হ'ল কোড অবদানকারী হয়ে উঠুন! যে কোনও সময় আপনি পাইসাইফ্ট গিটহাবে ইস্যু পৃষ্ঠাতে যেতে পারেন এবং \"প্রকল্পগুলি\" এর জন্য ফিল্টার করতে পারেন। এটি আপনাকে শীর্ষ স্তরের সমস্ত টিকিট দেখিয়ে দেবে যে আপনি কোন প্রকল্পগুলিতে যোগদান করতে পারেন তার একটি ওভারভিউ দেয়! আপনি যদি কোনও প্রকল্পে যোগ দিতে না চান তবে আপনি কিছুটা কোডিং করতে চান তবে আপনি \"ভাল প্রথম ইস্যু\" চিহ্নিত গিথুব ইস্যুগুলি অনুসন্ধান করে আরও \"ওয়ান অফ\" মিনি-প্রকল্পগুলির সন্ধান করতে পারেন।\n",
    "\n",
    "- [PySyft Projects](https://github.com/OpenMined/PySyft/issues?q=is%3Aopen+is%3Aissue+label%3AProject)\n",
    "- [Good First Issue Tickets](https://github.com/OpenMined/PySyft/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22)\n",
    "\n",
    "### দান করা (Donate)\n",
    "\n",
    "আপনার যদি আমাদের কোডবেসে অবদান রাখার সময় না থাকে তবে তবুও সমর্থন দিতে চান, আপনি আমাদের ওপেন কালেক্টিভেরও Backer হয়ে উঠতে পারেন। সমস্ত অনুদান আমাদের ওয়েব হোস্টিং এবং অন্যান্য সম্প্রদায় ব্যয় যেমন হ্যাকাথনস এবং মেটআপগুলির (hackathons and meetups!) দিকে যায়!\n",
    "\n",
    "- [Donate through OpenMined's Open Collective Page](https://opencollective.com/openmined)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.4"
  },
  "nbTranslate": {
   "displayLangs": [
    "*"
   ],
   "hotkey": "alt-t",
   "langInMainMenu": true,
   "sourceLang": "en",
   "targetLang": "fr",
   "useGoogleTranslate": true
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
